package com.vibration.matlab;

import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.vibration.common.config.VibrationConfig;
import com.vibration.socket.util.SocketUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.io.File;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 得到图像
 */
public class GetPlotImage {

    /**
     * 初始化数据开始
     */
    private static double[][] AP={{0.5000}}; //初始化

    private static double[][] apsv={{0.0050}};//初始化

    private static double[][] EA={{0.1000}};//初始化

    private static double[][] F1={}; //初始化

    private static double[][] F2={}; //初始化

    private static double[][] fgd1={}; //初始化

    private static  double[][] HHS={{1}}; //初始化

    private static double[][] ini1={}; //初始化

    private static int INPO=50; //初始化

    private static double[][] kb_by_dk={{1000.0}}; //初始化

    private static double[][] mkb_by_dk={{2000.0}}; //初始化

    private static int NC=0; //初始化

    private static char[][] NUMW={{'6'}}; //初始化

    private static double[][] open={{0}}; //初始化

    private static double[][] Perr={}; //初始化

    private static double[][] ramasL={{5.0}}; //初始化

    private static double[][] ramasR={{5.0}}; //初始化

    private static double[][] RT={{0.9000}}; //初始化

    private static double[][] T0={{1}}; //初始化

    private static double[][] Tinv={{1}}; //初始化

    private static double[][] ZLVp={{1}}; //初始化

    private static double[][] ZLVs={{0}}; //初始化

    private static double[][] pmy={{0}}; //初始化

    private static double[][] ww={{0}}; //初始化

    private static double[][] stdgDC={{3}};//初始化

    private static double[][] stdgHV={{2}};//初始化

    private static double[][] pass={{1}};//初始化

    private static double[][] stdg={{2}};//初始化
    /**
     * 初始化数据结束
     */

    //写死数据
    private static double[][] flag={{1}}; //因为是H/V模式


    private static A a=new A();
    private static C c=new C();


    //定义MM
    private static double[][] MM={{0}};

    //定义NPI
    private static double[][] NPI={{0}};

    //定义aopt
    private static double[][] aopt={};


    private static double[][] L2i={};

    private static double[][] L2ip={};


    private static int limdd=150;


    /**
     * function[aopt,aini,L2i1,L2opt,L2optimo,DCopt,HVopt,NN1,NN2] =getFirstData(A,DCT,HVT,L2i,mod)
     * [~ ,b]=sort(L2i);%Ordenando el misfit de menor a mayor
     * aopt=mod(:,:,b(1));%Ordenando midelos de menor a mayor el misfit
     * [L2i1,L2opt,L2optimo]=deal(L2i(b(1)));
     * [NN1,NN2]=deal(A.NN/100);
     * [DCopt,HVopt,aini]=deal(DCT(:,b(1)),HVT(:,b(1)),aopt);
     * end
     */
    private static double[][][] mod={};

    private static double[][] HVT={};

    private static double[][] DCT={};


    /**
     * opt迭代计算函数参数
     */
    private static double T1;
    private static double TSAM;

    private static double[][] indata={};


    public static TransInfo getPlotImage(int NC,double[][] HVC,double Vstd,int INPO) throws Exception {
        /**
         * 得到结构体即C的数据
         */
        //设置误差棒
        if(Vstd==0.0){
            Vstd=10.0;
        }
        TransInfo getInitC=GetC.getCData(c,HVC,Vstd);
        c=getInitC.getC();
        /**
         * 测试误差棒
         */
//        for (int i=0;i<c.getHVDS().length;i++){
//            for (int j=0;j<c.getHVDS()[0].length;j++){
//                System.out.print("得到数据HVDS"+c.getHVDS()[i][j]);
//            }
//            System.out.println("------------------");
//        }
        /**
         * 拿到HVC
         */
         for (int i=0;i<HVC.length;i++){
            for (int j=0;j<HVC[0].length;j++){
                System.out.print("得到数据HVC"+HVC[i][j]);
            }
            System.out.println("------------------");
        }

        /**
         * 设置apsv
         */
        a.setApsv(apsv);
        /**
         * 测试表格初始化得到数组
         * NC为厚度
         * inData为表格数据
         */
        TransInfo transInfoInit= InitModelParamters.getInitModelParameters(NC,a,limdd,INPO,indata);

        INPO=transInfoInit.getINPO();
        a=transInfoInit.getA();
        limdd=transInfoInit.getLimdd();
        /**
         * 得到显示的数据
         */
        double[][] getData=transInfoInit.getData();
        //表格展示的数据
//        for(int i=0;i<getData.length;i++){
//            for (int j=0;j<getData[0].length;j++){
//                System.out.print("得到数据"+getData[i][j]);
//            }
//            System.out.println("------------------------------");
//        }

        /**
         * 测试A的数据 现在得到是a的数据
         */
        TransInfo getInitA=GetA.getA(a);
        a=getInitA.getA();

        /***
         * 随机生成图像数据开始=============================
         */
        /**
         *  测试random search 开始
         */
        double[][] ProbLimSupSegHHS=a.getProbLimSupSegHHS();
        double[][] LimVelSegHHS=a.getLimVelSegHHS();
        int MM=0;
        double[][] ini1={};
        double pass=1.0;
        //apsv正常
//        System.out.println("得到apsv"+a.getApsv()[0][0]);
        //limd正常
//        System.out.println("得到limd"+a.getLimd()[0][0]);
        //var数组正常
//        for (int i=0;i<a.getVar().length;i++){
//            for (int j=0;j<a.getVar()[0].length;j++){
//                System.out.println("得到数据Var"+a.getVar()[i][j]);
//            }
//        }
        //NC正常
//        System.out.println("得到NC"+a.getNC());

        /**
         * 参数limsg正常 参数pol正常
         */
//        for (int i=0;i<a.getLimseg().length;i++){
//            for (int j=0;j<a.getLimseg()[0].length;j++){
//                System.out.println("得到数据Limseg"+a.getLimseg()[i][j]);
//            }
//        }
        System.out.println("得到INPO"+INPO);
        G g=new G();
        Object[] res=GetRandomSearch.getRandomSearch(a,c,g,1,INPO,ini1,pass,ProbLimSupSegHHS,LimVelSegHHS);
        /**
         * 得到L2i
         */
        MWNumericArray getL2i= (MWNumericArray)res[0];
        L2i=(double[][]) getL2i.toDoubleArray();
//
        /**
         * 得到pass
         */
        MWNumericArray getPass= (MWNumericArray)res[1];
        double[][] getDoublePass=(double[][]) getPass.toDoubleArray();
        pass=getDoublePass[0][0];
        /**
         * 得到mod
         */
        MWNumericArray getMod= (MWNumericArray)res[2];
        mod=(double[][][]) getMod.toDoubleArray();
        /**
         * 得到DCT
         */
        MWNumericArray getDCT= (MWNumericArray)res[3];
        DCT=(double[][]) getDCT.toDoubleArray();

        /**
         * 得到HVT
         */
        MWNumericArray getHVT= (MWNumericArray)res[4];
        HVT=(double[][]) getHVT.toDoubleArray();


        Object[] response= GetData.getData(a,DCT,HVT,L2i,mod);
        /**
         * 获取aopt  得到第一组随机矩阵
         */
        MWNumericArray getAopt= (MWNumericArray)response[0];
        aopt=(double[][]) getAopt.toDoubleArray();

        /**
         * 获取A.aini
         */
        MWNumericArray getAini= (MWNumericArray)response[1];
        double[][] aini=(double[][]) getAini.toDoubleArray();
        a.setAini(aini);
        /**
         * 获取L2i1
         */
        MWNumericArray getL2i1= (MWNumericArray)response[2];
        double[][] L2i1=(double[][]) getL2i1.toDoubleArray();

        /**
         * 获取A.L2opt
         */
        MWNumericArray getL2opt= (MWNumericArray)response[3];
        double[][] L2opt=(double[][]) getL2opt.toDoubleArray();
        a.setL2opt(L2opt);
        /**
         * 获取A.L2optimo
         */
        MWNumericArray getL2optimo= (MWNumericArray)response[4];
        double[][] L2optimo=(double[][]) getL2optimo.toDoubleArray();
        a.setL2optimo(L2optimo);
        /**
         * 获取DCopt
         */
        MWNumericArray getDCopt= (MWNumericArray)response[5];
        double[][] DCopt=(double[][]) getDCopt.toDoubleArray();
        /**
         * 获取HVopt
         */
        MWNumericArray getHVopt= (MWNumericArray)response[6];
        double[][] HVopt=(double[][]) getHVopt.toDoubleArray();

        /**
         * 获取A.NN1
         */
        MWNumericArray getNN1= (MWNumericArray)response[7];
        double[][] NN1=(double[][]) getNN1.toDoubleArray();
        a.setNN1(NN1);
        /**
         * 获取A.NN2
         */
        MWNumericArray getNN2= (MWNumericArray)response[8];
        double[][] NN2=(double[][]) getNN2.toDoubleArray();
        a.setNN2(NN2);


        /**
         * 拿T1参数 TSAM参数
         */
        TransInfo getT1=GetT1.getT1Data(a,T1,TSAM);

        double[][] Tfin={{0}};
        double[][] mac={{0}};
        double[][] Tfin2={{0}};

        Cont cont=new Cont();

        TSAM=getT1.getTSAM();
        T1=getT1.getT1();

        /**
         * 调用opt计算函数  计算最终数据
         */
        TransInfo transInfo=GetFinalData.getFinalData(a,c,g,Tinv,TSAM,MM,cont,aopt,
                L2i1,Tfin,Tfin2,T1,mac,ini1,HVopt);
        /**
         * 最终aopt
         */
        double[][] aopt=transInfo.getAopt();
        /**
         * 误差棒
         */
        double[][] HVDS=c.getHVDS();
        /**
         * x轴
         */
        double[][] HVFobs=c.getHVFobs();
        /**
         * 黑线y轴
         */
        double[][] HVAobs=c.getHVAobs();
        /**
         * 红线y轴
         */
        HVopt=transInfo.getHVopt();

        /**
         * 测试plot图像  生成左侧图像
         * limdd必须传int整型
         */
        TransInfo t= GetPlotLeft.getPlot(a.getLimd()[0][0],limdd,aopt);
        transInfo.setLeftImageFileName(t.getLeftImageFileName());
        //设置Vs的X,Y轴
        transInfo.setVsXYData(t.getVsXYData());
        //设置Vp的X,Y轴
        transInfo.setVpXYData(t.getVpXYData());
        //设置Vp的X轴
        transInfo.setVpXData(t.getVpXData());
        //设置Vs的X轴
        transInfo.setVsXData(t.getVsXData());
        //设置X轴
        transInfo.setYData(t.getYData());
//
//        /**
//         * 测试plot图像 生成右侧图像
//         * (double[][] HVDS,double[][] HVFobs,double[][] HVAobs,double[][] HVopt)
//         */
        String rightFileName=GetPlotRight.getRightPlot(HVDS,HVFobs,HVAobs,HVopt);
        transInfo.setRightImageFileName(rightFileName);

        String pathName= VibrationConfig.getInversionPath()+"/"+ SocketUtil.inversionTask+"/"+"leftData.txt";
        File file=new File(pathName);
        if(!file.exists()){
            try{
                file.createNewFile();
            }
            catch (IOException e){
                e.printStackTrace();
            }
        }
        //写入左图数据
        writeArrayToTxt(transInfo.getVsXYData(),transInfo.getVpXYData(),pathName);

        String pathName2=VibrationConfig.getInversionPath()+"/"+ SocketUtil.inversionTask+"/"+"rightData.txt";
        File file2=new File(pathName2);
        if(!file2.exists()){
            try{
                file2.createNewFile();
            }
            catch (IOException e){
                e.printStackTrace();
            }
        }

        /**把数据转为一维数组**/
        double[] getHVDSData=new double[HVDS.length];
        for(int i=0;i<HVDS[0].length;i++){
            for (int j = 0; j <HVDS.length; j++) {
                getHVDSData[j]=HVDS[j][0];
            }
        }

        /**把数据转为一维数组**/
        double[] getHVFobsData=new double[HVFobs.length];
        for(int i=0;i<HVFobs[0].length;i++){
            for (int j = 0; j <HVFobs.length; j++) {
                getHVFobsData[j]=HVFobs[j][0];
            }
        }

        /**把数据转为一维数组**/
        double[] getHVAobsData=new double[HVAobs.length];
        for(int i=0;i<HVAobs[0].length;i++){
            for (int j = 0; j <HVAobs.length; j++) {
                getHVAobsData[j]=HVAobs[j][0];
            }
        }
        /**把数据转为一维数组**/
        double[] getHVoptData=new double[HVopt.length];
        for(int i=0;i<HVopt[0].length;i++){
            for (int j = 0; j <HVopt.length; j++) {
                getHVoptData[j]=HVopt[j][0];
            }
        }

        /**四个一维数组转二维**/
        //定义二维数组
        double[][] getTotalData=new double[HVDS.length][4];
        //把一维数组合并为二维
        for(int i=0;i<HVDS.length;i++){
            getTotalData[i][0]=getHVoptData[i]; //红线y轴
            getTotalData[i][1]=getHVFobsData[i]; //x轴
            getTotalData[i][2]=getHVAobsData[i]; //黑线y轴
            getTotalData[i][3]=getHVDSData[i];  //误差棒
        }
        //写入右图数据
        writeArrayToTxt2(getTotalData,pathName2);

        return transInfo;
    }

    public static void writeArrayToTxt(double[][] data,double[][] data2, String string) {
        int rowNum = data.length;
        int columnNum = data[0].length;

        int rowNum2 = data2.length;
        int columnNum2 = data2[0].length;

        try {
            FileWriter fw = new FileWriter(string);

            fw.write("Y值"+ "\t");
            fw.write("Vs值"+ "\t");
            fw.write("\n");
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < columnNum; j++)
                    fw.write(data[i][j]+ "\t");
                fw.write("\n");
            }
            fw.write("Y值"+ "\t");
            fw.write("Vp值"+ "\t");
            fw.write("\n");
            for (int i = 0; i < rowNum2; i++) {
                for (int j = 0; j < columnNum2; j++)
                    fw.write(data2[i][j]+ "\t");
                fw.write("\n");
            }

            fw.close();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

    public static void writeArrayToTxt2(double[][] data, String string) {
        try {
            FileWriter fw = new FileWriter(string);
            fw.write("红线Y轴值"+ "\t\t\t");
            fw.write("X轴"+ "\t\t\t");
            fw.write("黑线Y轴值"+ "\t\t\t");
            fw.write("误差棒值"+ "\t\t\t");
            fw.write("\n");
            //遍历四维数组
            for (int i = 0; i <data.length ; i++) {
                for (int j = 0; j <data[0].length ; j++) {
                            fw.write(data[i][j]+ "\t\t\t");
                }
                fw.write("\n");
            }

            fw.close();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }


}
